<?php
set_time_limit(6000000);
/**
 * @author Pouja 'PawyaBoy' Nikray
 */
class Database{
    private $link;
    private $error;
    
    /**
     *  Creates the database by initializing its attributes and connections 
     */
    public function Database(){
        if(!isset($_SESSION)){
            session_start();
            session_regenerate_id();
   
        }
        require("mysql.db");
        $this->link=mysql_connect("sql.ewi.tudelft.nl","ikemusic2",$ps);
        unset($ps);
        $this->error=array();
        if(!$this->link){
                $this->$succes=false;
                $this->error[]=mysql_error();
        }
        $db=mysql_select_db("ikemusic2",$this->link);
        if(!$db){
            $this->error[]=mysql_error();
        }
    }

    /**
     * Logs a user out by destroying his session
     */
    public function logOut(){
        session_destroy();
        unset($_SESSION);
        print('logged out');
    }

    /**
     *Clears the variable from the cache
     * @param type $var 
     */
    public function removeCache($var){
        if(array_key_exists($var, $_SESSION)){
            unset($_SESSION[$var]);
        }
    }
    

    /**
     * Check a user by his username and password using a passwordHash
     * @param type $userName
     * @param type $password
     * @return type 
     */
    public function checkUser($userName,$password){
        $query="SELECT * FROM User WHERE Name='".$userName."'";
        $result=mysql_query($query,$this->link);
        print(mysql_error());
        $count=mysql_num_rows($result);
        //numeric username, password match; -1 user doesn't exist; -2 password doesnt match
        $cryp=new PasswordHash(8, FALSE);
        if($count<1){
            return -1;
        }
        while($row=  mysql_fetch_array($result)){
            if($cryp->CheckPassword($password, $row['password'])){
                return $row['id'];
            }
        }
        return -2;
    }

    /**
     * Process a rating by updating usertrack. A user should be logged in, and if that is 
     * the case, the userGenre table will also be updated to fit his averageRating per genre
     * @param type $trackID
     * @param type $rating 
     */
    public function rate($trackID,$rating){
        $idUser=$this->getCache('user');
        $query='SELECT rating FROM NewUserTrack WHERE idUser='.$idUser.' AND idTrack = '.$trackID;
        $result=mysql_query($query);
        $row=mysql_fetch_array($result);
        $difference = $rating-$row['rating'];
        mysql_query('UPDATE NewUserTrack SET rating='.$rating.' WHERE idTrack='.$trackID.' AND idUser='.$idUser);
        if($idUser>0)
        {
            $query2='SELECT count, rating FROM NewUserGenre WHERE idUser='.$idUser;
            $result2=mysql_query($query2);
            $row2=mysql_fetch_array($result2);
            $oldRating = $row2['rating'];
            $count = $row2['count'];
            $newRating = (double)(($oldRating*$count + $difference)/($count));
            var_dump($newRating);
            $query='SELECT Genre1ID, Genre2ID, Genre3ID FROM NewArtistGenre, NewArtist, NewAlbum, NewTrack WHERE NewTrack.id = '.$trackID.' AND NewTrack.idAlbum = NewAlbum.id AND NewAlbum.idArtist = NewArtist.id AND NewArtistGenre.ArtistID=NewArtist.id';
            $result=mysql_query($query);
            $row=mysql_fetch_array($result);
            for($i = 1; $i < 4; $i++)
                mysql_query('UPDATE NewUserGenre SET rating='.$newRating.' WHERE idUser='.$idUser.' AND idGenre = '.$row['Genre'.$i.'ID']);
        }
    }
    
    /**
     * Return the rating for a given user, or 3 if not logged in
     * @param type $trackID
     * @return type 
     */
    public function getRating($trackID){
        $idUser=$this->getCache('user');
        if(!$idUser){
            return 3;
        }
        $query='SELECT rating FROM NewUserTrack WHERE idUser='.$idUser.' AND idTrack='.$trackID;
        $result=mysql_query($query);
        $row=mysql_fetch_array($result);
        return $row[0];
    }
    
    /**
     * Log a user in by checking the user and returning his id if not already logged in
     * @param type $userName
     * @param type $password
     * @return type 
     */
    public function logIn($userName,$password){
        $id=$this->checkUser($userName, $password);
        if(!$this->getCache('user') && $id>=0){
            $this->cache('user', (int)$id);
            return 1;
        }
        return $id;
    }

    /**
     * Return a user by an id
     * @param int $id The id
     * @return User user The user or null if 
     */
    public function getUser($id){
        if(is_int((int)$id)){
            $query='SELECT * FROM User WHERE id='.$id;
            $result=mysql_query($query);
            if(mysql_num_rows($result)>0){
                $row=mysql_fetch_array($result);
                $user=new User();
                $user->setEmail($row['email']);
                $user->setUserName($row['Name']);
                return $user;
            }
        }
        return null;
    }
        
    /**
     * Register a user by creating a new account
     * @param type $idUser
     * @param type $password
     * @return type 
     */
    public function register($idUser,$password)
    {
        $cryp=new PasswordHash(8, FALSE);
        $cryptedPass=$cryp->HashPassword($password);
        if(is_int($idUser)){
            $query='UPDATE User SET password="'.$cryptedPass.'" WHERE id='.$idUser;
            $result=mysql_query($query);
            print(mysql_error());
            return true;
        }
        return false;
    }
    
    /**
     * Create a new artist object in the database
     * @param Artist $artist
     * @return type 
     */
    public function newArtist($artist){
        if($artist instanceof Artist){
            $name=$artist->name();
            $genre1=$genre2=$genre3=$genre4=$genre5='';
            $genres=$artist->genres();
            for($i=0;$i<count($genres);$i++){
                $var='genre'.($i+1);
                $$var=$genres[$i];
            }
            $years=$artist->yearActive();
            $year1=$years[0];
            $year2=$years[1];
            $listened=$artist->listened();
            mysql_query("INSERT INTO NewArtist (name, listened, genre1, genre2, genre3, genre4, genre5, year1,year2,similar1,similar2,similar3,similar4,similar5) VALUES ('".$name."','".$listened."','".$genre1."','".$genre2."','".$genre3."','".$genre4."','".$genre5."','".$year1."','".$year2."')");
            $id=mysql_insert_id();
            if(is_int($id)){
                $artist->setID($id);
                $similars=$artist->similar();
                $similar1=$similar2=$similar3=$similar4=$similar5='';
                for($i=0;$i<count($similars);$i++){
                    $var='similar'.($i+1);
                    $$var=$similars[$i]->id();
                }
                mysql_query("INSERT INTO Similar (ArtistID,Similar1ID,Similar2ID,Similar3ID,Similar4ID,Similar5ID) VALUES ('".$artist->id()."','".$similar1."','".$similar2."','".$similar3."','".$similar4."','".$similar5."'");

                $albums=$artist->albums();
                if(count($albums)>0){
                    if($albums[0] instanceof Album){
                        for($i=0;$i<count($albums);$i++){
                            newAlbum($albums[$i],$artist->id());
                        }
                    }
                }
            }
            return $artist->id();
        }
    }
    
    /**
     * Create a new album object in the database
     * @param Album $album
     * @param type $artistID 
     */
    public function newAlbum($album,$artistID){
        if($album instanceof Album){
            $name=mysql_real_escape_string($album->name());
            $image=mysql_real_escape_string($album->cover());
            $info=mysql_real_escape_string($album->info());
            mysql_query('INSERT INTO NewAlbum (idArtist,name,info,image) VALUES ("'.$artistID.'","'.$name.'","'.$info.'","'.$image.'")');
            print(mysql_error());
            $idAlbum=mysql_insert_id();
            
            if(is_int($idAlbum)){
                $album->setID($idAlbum);
                $track=$album->songs();
                for($i=0;$i<count($track);$i++){
                    $this->newTrack($track[$i],$album->id());
                }
            }
        }
    }
    
    /**
     * Create a new track object in the database
     * @param Track $track
     * @param type $albumID
     * @return type 
     */
    public function newTrack($track,$albumID){
        if($track instanceof Track){
            $name=mysql_real_escape_string($track->name());
            mysql_query('INSERT INTO NewTrack (idAlbum,name) VALUES ("'.$albumID.'","'.$name.'")');
            
            print(mysql_error());
            return mysql_insert_id();
        }
    }
    
    /**
     * Create a new user object in the database
     * @param User $user
     * @param type $password
     * @return type 
     */
    public function newUser($user,$password){
        if($user instanceof User){ 
            $name=mysql_real_escape_string($user->userName());
            $email=mysql_real_escape_string($user->email());
            
            $query='SELECT * FROM User WHERE Name="'.$name.'" OR email="'.$email.'"';
            $result=mysql_query($query);
            $countRows=mysql_num_rows($result);
            if($countRows==0){
                mysql_query('INSERT INTO User (Name,email) VALUES ("'.$name.'","'.$email.'")');
                print(mysql_error());
                $idUser=mysql_insert_id();
                $user->setID($idUser);
                $out=$this->register($idUser,$password);
                if($out){
                    return $idUser;
                }
                return "Error!";
            }
            return "This user already exists";
        }
    }
    
    /**
     * Return a track by a given trackID
     * @param type $id
     * @return Track 
     */
    public function getTrackByID($id,$full=true){
        $track=new Track();
        $track->setID($id);
        
        $result=mysql_query('SELECT * FROM NewTrack WHERE id="'.$id.'"');
        $row=mysql_fetch_array($result);
        $track->setName($row['name']);
        if($full){
            $queryListened=mysql_query('SELECT sum(listened) FROM NewUserTrack WHERE idTrack="'.$id.'"');
            $rowListened=mysql_fetch_array($queryListened);
            $track->setListened($rowListened[0]);

            $queryRating=mysql_query('SELECT sum(rating)/count(distinct rating) FROM NewUserTrack WHERE idTrack="'.$id.'"');
            $rowRating=mysql_fetch_array($queryRating);
            $track->setRating($rowRating[0]);
        }
        return $track;
    }
    
    /**
     * Return a track by its name, is sensitive to duplicates because tracknames may be non-unique
     * @param type $name
     * @param type $id
     * @param type $album
     * @return type 
     */
    public function getTrackByName($name,$id,$album=true){
        $name=mysql_real_escape_string($name);
        $query;
        if($album){
            $query='SELECT id FROM NewTrack WHERE name="'.$name.'" AND idAlbum='.$id;
        }
        else{
            $query="SELECT NewTrack.id FROM NewTrack, NewAlbum WHERE NewTrack.name='".$name."' AND NewTrack.idAlbum = NewAlbum.id AND NewAlbum.idArtist = '".$id."'";
        }
        $result=mysql_query($query);
        print(mysql_error());
        
        $row=mysql_fetch_array($result);
        $countRows=mysql_num_rows($result);
        
        if($countRows==0){
            return null;
        }
        return $this->getTrackByID($row[0]);
    }
    
    /**
     * Returns whether an artist has a given track
     * @param type $artistID
     * @param type $trackName
     * @return type 
     */
    public function artistHasTrack($artistID, $trackName)
    {   $trackName=mysql_real_escape_string($trackName);
        $query = 'SELECT DISTINCT NewTrack.id, NewTrack.name FROM NewTrack, NewAlbum WHERE NewAlbum.idArtist = '.$artistID.' AND NewTrack.idAlbum = NewAlbum.id AND NewTrack.name = "'.$trackName.'"';
        $result=mysql_query($query);
        print(mysql_error());
        if(mysql_num_rows($result) > 0)
            return true;
        return false;
    }
    
    /**
     * Returns whether an artist has any known tracks
     * @param type $artistID
     * @return type 
     */
    public function artistHasTracks($artistID)
    {
        $query = 'SELECT DISTINCT NewTrack.id FROM NewTrack, NewAlbum, NewArtist WHERE NewArtist.id = '.$artistID.' AND NewAlbum.idArtist = NewArtist.id AND NewTrack.idAlbum = NewAlbum.id LIMIT 1';
        $result=mysql_query($query);
        if(mysql_num_rows($result) > 0)
            return true;
        return false;
    }
    
    /**
     * Returns an album based on an id
     * @param type $id
     * @param type $full
     * @param type $limitTracks
     * @return Album 
     */
    public function getAlbumByID($id,$full=true,$limitTracks=null){
        $album=new Album();
        $album->setID($id);
        $result=mysql_query('SELECT * FROM NewAlbum WHERE id='.$id);
        $countRows=mysql_num_rows($result);
        if($countRows==0){
            return null;
        }
        $row=mysql_fetch_array($result);
        $album->setCover($row['image']);
        $album->setName($row['name']);
        $album->setInfo($row['info']);
        if($full){
            $resultTrack=mysql_query('SELECT id FROM NewTrack WHERE idAlbum='.$id);
            if($limitTracks!=null){
                while($row = mysql_fetch_array($resultTrack)){
                    if($limitTracks<=0){break;}
                    $limitTracks--;
                    $album->addTrack($this->getTrackByID($row[0]));

                }
            }
            else{
                while($row = mysql_fetch_array($resultTrack)){
                    $album->addTrack($this->getTrackByID($row[0]));
                }
            }
        }
        return $album;
    }

    /**
     * Checks if an album appears in the table of known empty ablums 
     * @param type $name
     * @param type $artistID
     * @return type 
     */
    public function checkIfEmptyAlbum($name,$artistID){
        $name=mysql_real_escape_string($name);
        $query='SELECT id FROM EmptyAlbum WHERE name="'.$name.'" AND idArtist='.$artistID;
        $result=mysql_query($query);
        print(mysql_error());
        $countRows=mysql_num_rows($result);
        if($countRows!=0){
            return true;
        }
        return false;
    }

    /**
     * Adds an album to the table of known empty albums
     * @param Album $album
     * @param type $artistID 
     */
    public function addEmptyAlbum($album,$artistID){
        if($album instanceof Album){
            $name=mysql_real_escape_string($album->name());
            mysql_query('INSERT INTO EmptyAlbum (idArtist,name) VALUES ("'.$artistID.'","'.$name.'")');
            print(mysql_error());
        }
    }

    /**
     * Returns an album based on a name and an artist ID; usually unique results
     * @param type $name
     * @param type $artistID
     * @return type 
     */
    public function getAlbumByName($name,$artistID){
        $name=mysql_real_escape_string($name);
        $query='SELECT id FROM NewAlbum WHERE name="'.$name.'" AND idArtist='.$artistID;
        $result=mysql_query($query);
        $row=mysql_fetch_array($result);
        $countRows=mysql_num_rows($result);
        if($countRows==0){
            return null;
        }
        return $this->getAlbumByID($row[0]);
    }

    /** 
     * Returns an album based on a track name and an artist ID. May be non-unique
     * @param type $trackName
     * @param type $artistID
     * @param type $scarce
     * @return Album 
     */
    public function getAlbumByTrackName($trackName, $artistID, $scarce=true){
         if(is_int((int)$artistID)){
             if($scarce){
                 $query='SELECT NewAlbum.id AS id, NewAlbum.name AS name FROM NewAlbum, NewTrack WHERE NewAlbum.idArtist = '.$artistID.' AND NewTrack.idAlbum = NewAlbum.id AND NewTrack.name = "'.$trackName.'"';
                 $result=mysql_query($query);
                 $row=mysql_fetch_array($result);
                 if(mysql_num_rows($result)==0){
                     return null;
                 }
                 $album = new Album();
                 $album->setID($row['id']);
                 $album->setName($row['name']);
                 return $album;
             } 
         }
    }
    
    /**
     * Returns whether an artist already has the default album
     * @param type $artistID
     * @return type 
     */
    public function artistHasDefaultAlbum($artistID)
    {
        $query = 'SELECT NewArtist.id FROM NewArtist, NewAlbum WHERE NewArtist.id = '.$artistID.' AND NewAlbum.idArtist = NewArtist.id AND NewAlbum.name = "DefaultAlbum"';
        if(mysql_num_rows(mysql_query($query)) > 0)
            return true;
        return false;
    }
    

    /** 
     * Creates a default album for an artist
     * @param type $artistID
     * @return type 
     */
    public function artistCreateDefaultAlbum($artistID)
    {
        $update = 'INSERT INTO NewAlbum (idArtist, name) VALUES ('.$artistID.', "DefaultAlbum")';
        mysql_query($update);
        return mysql_insert_id();
    }
    
    /**
     * Returns an artist based on an ID
     * @param type $id
     * @param type $similar
     * @param type $full
     * @param type $limitAlbums
     * @param type $limitTracks
     * @return Artist 
     */
    public function getArtistByID($id,$similar=true,$full=true,$limitAlbums=null,$limitTracks=null){
        if(is_int((int)$id)){
            $query='SELECT * FROM NewArtist WHERE id="'.$id.'"';
            $result=mysql_query($query);
            print(mysql_error());
            $artist=new Artist();
            while($row = mysql_fetch_array($result)){
                $artist->setID($id);
                $artist->setListeners($row['listened']);
                $artist->setName($row['name']);
                
                $query2='SELECT NewGenre.name FROM NewGenre, NewArtistGenre WHERE ArtistID="'.$id.'" AND Genre1ID = NewGenre.id';
                $result2 = mysql_query($query2);
                print(mysql_error());
                $row2 = mysql_fetch_array($result2);
                $artist->addGenre($row2['name']);
                $query2='SELECT NewGenre.name FROM NewGenre, NewArtistGenre WHERE ArtistID="'.$id.'" AND Genre2ID = NewGenre.id';
                $result2 = mysql_query($query2);
                print(mysql_error());
                $row2 = mysql_fetch_array($result2);
                $artist->addGenre($row2['name']);
                $query2='SELECT NewGenre.name FROM NewGenre, NewArtistGenre WHERE ArtistID="'.$id.'" AND Genre3ID = NewGenre.id';
                $result2 = mysql_query($query2);
                print(mysql_error());
                $row2 = mysql_fetch_array($result2);
                $artist->addGenre($row2['name']);
                
                /*
                $artist->addGenre($row['genre1']);
                $artist->addGenre($row['genre2']);
                $artist->addGenre($row['genre3']);
                $artist->addGenre($row['genre4']);
                $artist->addGenre($row['genre5']);*/
                $artist->setYearActive($row['year1'], $row['year2']);
                break;
            }
            $queryAlbums='SELECT id FROM NewAlbum WHERE idArtist="'.$id.'"';
            $resultAlbums=mysql_query($queryAlbums);
            if($limitAlbums==null){
                while($row = mysql_fetch_array($resultAlbums)){
                    $artist->addAlbum($this->getAlbumByID($row[0], $full, $limitTracks));
                }
            }
            else{
                while($row = mysql_fetch_array($resultAlbums) && $limitAlbums!=0){
                    $artist->addAlbum($this->getAlbumByID($row[0], $full, $limitTracks));
                    $limitAlbums--;
                }
            }
            return $artist;
        }
    }
    
    /**
     * Returns an artist based on a name. Usually unique
     * @param type $name
     * @param type $full
     * @return type 
     */
    public function getArtistByName($name, $full=true){
        if(strlen($name)>1){
            $query='SELECT id FROM NewArtist WHERE LOWER(name) LIKE "%'.strtolower($name).'%" ORDER BY listened DESC LIMIT 1';
            $result = mysql_query($query);
            
            while($row = mysql_fetch_array($result)){
                return $this->getArtistByID((int)$row[0], false, $full);
                break;
            }
        }
    }
    
    /**
     * Returns the current user from cache
     * @return User user The current user that is logged in or null if the user is not logged in 
     */
    public function getCurrentUser(){
        $id=$this->getCache('user');
        return $this->getUser($id);
    }
    
    /**
     * Process the information that a user is listening to a givent track
     * The table NewUserGenre is always updated for userID = 0, to keep track of 
     * the total activity on the site.
     * @param type $artistID
     * @param type $trackID
     * @return type 
     */
    public function setListening($artistID,$trackID){
        $idUser=$this->getCache('user');
        $artist=$this->getArtistByID($artistID, false,false,0,0);
        $genres=$artist->genres();
        
        // FOR EVERY USER:
               
        foreach($genres AS $genre){
            $queryGenreID = 'SELECT id FROM NewGenre WHERE name = "'.$genre.'"';
            $queryGenreIDResult = mysql_query($queryGenreID);
            $queryGenreIDRow = mysql_fetch_array($queryGenreIDResult);
            $genreID = $queryGenreIDRow['id'];
            $queryU='SELECT count FROM NewUserGenre WHERE NewUserGenre.idUser = 0 AND NewUserGenre.idGenre = '.$genreID;
            $resultU=mysql_query($queryU);
            print(mysql_error());
            $countRows=mysql_num_rows($resultU);
            if($countRows==1){
                $row=mysql_fetch_array($resultU);
                $oldCount=$row['count'];
                mysql_query('UPDATE NewUserGenre SET count='.($oldCount+1).' WHERE idUser = 0 AND idGenre = '.$genreID);
                print(mysql_error());
            }
            else{
                mysql_query('INSERT INTO NewUserGenre (idUser,idGenre,count, rating) VALUES(0,'.$genreID.',1, 3)');
                print(mysql_error());
            }
        }
        
        // IF NOT LOGGED IN:
              
        if($idUser==null){
            $queryL='SELECT listened FROM NewUserTrack WHERE idTrack='.$trackID.' AND idUser=0';
            $resultL=mysql_query($queryL);
            print(mysql_error());
            $countRows=mysql_num_rows($resultL);
            if($countRows==1){
                $row=mysql_fetch_array($resultL);
                $oldCount=$row['listened'];
                mysql_query('UPDATE NewUserTrack SET listened='.($oldCount+1).' WHERE idTrack='.$trackID.' AND idUser=0');
                print(mysql_error());
            }
            else{
                mysql_query('INSERT INTO NewUserTrack (idUser,idTrack,listened, rating) VALUES(0,"'.$trackID.'",1, 3)');
                print(mysql_error());
            }
            return;
        }
        
        // IF LOGGED IN:
              
        // Create the array to store the scores for every genre
        $idGenre=array();
        for($i=0;$i<count($genres);$i++){
            $query='SELECT id FROM NewGenre WHERE name="'.$genres[$i].'"';
            $result=mysql_query($query);
            $row=mysql_fetch_array($result);
            if($row){
                array_push($idGenre,$row[0]);
            }
        }
        //Update genre counts and ratings where necessary
        for($i=0;$i<count($idGenre);$i++){
            $queryF='SELECT count, rating FROM NewUserGenre WHERE idUser="'.$idUser.'" AND idGenre="'.$idGenre[$i].'"';
            $resultF=mysql_query($queryF);
            print(mysql_error());
            $rowF=mysql_fetch_array($resultF);

            if(!$rowF){
                $count = 0;
                mysql_query('INSERT INTO NewUserGenre VALUES("'.$idUser.'", "'.$idGenre[$i].'", 1, 3)');
            }
            else {
                $count=$rowF[0];
                $newRating = (($rowF['rating']*$count)+3)/($count+1);
                var_dump($rowF['rating']*$count+3);
                var_dump($count+1);
                mysql_query('UPDATE NewUserGenre SET count="'.($count+1).'", rating="'.($newRating).'" WHERE idUser="'.$idUser.'" AND idGenre="'.$idGenre[$i].'"');
            }
            mysql_affected_rows();
        }
            
        // Predict a rating for this user if he hasn't given one already, based on 
        // correlation with this artist.
        $queryL='SELECT listened FROM NewUserTrack WHERE idTrack='.$trackID.' AND idUser='.$idUser;
        $resultL=mysql_query($queryL);
        print(mysql_error());
        $countRows=mysql_num_rows($resultL);
        if($countRows==1){
            $row=mysql_fetch_array($resultL);
            $oldCount=$row['listened'];
            mysql_query('UPDATE NewUserTrack SET listened='.($oldCount+1).' WHERE idTrack='.$trackID.' AND idUser='.$idUser);
            print(mysql_error());
        }
        else{
            $query = 'SELECT * FROM NewUserGenre WHERE idUser = '.$idUser;
            $result=mysql_query($query);
            print(mysql_error());
            $array = array();
            $maxCount = 0;
            while($row=mysql_fetch_array($result))
            {
                $array[$row['idGenre']] = $row['count'];
                if($row['count'] > $maxCount)
                    $maxCount = $row['count'];
            }
            foreach($array as $id=>$genre) {
                $array[$id] /= $maxCount;
            }
            //var_dump($array);
            $score = 0;
            $count = 0;
            $query = 'SELECT Genre1ID, Genre2ID, Genre3ID FROM NewArtistGenre, NewArtist, NewAlbum, NewTrack WHERE NewTrack.id = "'.$trackID.'" AND NewAlbum.id = NewTrack.idAlbum AND NewArtist.id = NewAlbum.idArtist AND NewArtist.id = NewArtistGenre.ArtistID';
            $result = mysql_query($query);
            while($row=mysql_fetch_array($result))
            {
                for($i = 0; $i < 3; $i++)
                {
                    if($array[$row['Genre'.($i+1).'ID']])
                    {
                        $score += $array[$row['Genre'.($i+1).'ID']];
                        $count++;
                        //print($row['Genre$score']."  ");
                    }
                }
            }
            if($count > 0)
                $score /= $count;
            else
                $score = 0.5;
           // print("count and score: ".$count."  ".$score);
            mysql_query('INSERT INTO NewUserTrack (idUser,idTrack,listened, rating) VALUES("'.$idUser.'","'.$trackID.'",1, '.($score*4 + 1).')');
            print(mysql_error());
        }
    }

    /**
     * Return all playlists of this user
     * @return array 
     */
    function getPlaylists(){
        $idUser=$this->getCache('user');
        if($idUser!=null){
            $query='SELECT id FROM Playlist WHERE idUser='.$idUser;
            $result=mysql_query($query);
            $out=array();
            while($row=  mysql_fetch_array($result)){
                $playlist=$this->getPlaylistByID($row['id']);
                array_push($out,$playlist);
            }
            return $out;
        }
        return null;
    }

    /**
     * Overwrite a playlist
     * @param type $playlist 
     */
    function setPlaylist($playlist){
        $query='DELETE FROM Playlist WHERE id='.$playlist->id();
        mysql_query($query);
        var_dump($playlist);
        $this->addPlaylist($playlist);
    }
    
    /**
     * 
     * Return the names of all known playlists
     * @return array 
     */
    function getPlaylistNames(){
        $idUser=$this->getCache('user');
        if(is_int((int)$idUser)&&$idUser!=NULL){
            $query='SELECT id,name FROM Playlist WHERE idUser='.$idUser;
            $result=mysql_query($query);
            $out=array();
            while($row=  mysql_fetch_array($result)){
                $playlist=new Playlist();
                $playlist->setID($row['id']);
                $playlist->setName($row['name']);
                array_push($out,$playlist);
            }
            return $out;
        }
        else{
            return null;
        }
    }
    
    /**
     * Return the top playlists for a given artists, sorted by score as a product
     * of total listencount and average rating
     * @param type $artistName
     * @param type $count
     * @return array 
     */
    function getTopPlaylist($artistName,$count=3){
        $out=array();
        $query='SELECT albumID,artistID,name FROM
            (SELECT name,albumID,artistID, (listened*(rating/ratingC)) AS rate FROM
                (SELECT NewArtist.id AS artistID, NewAlbum.name AS name, NewAlbum.id AS albumID,SUM(NewUserTrack.listened) AS listened,SUM(NewUserTrack.rating) AS rating,COUNT(NewUserTrack.rating) AS ratingC FROM NewArtist,NewAlbum,NewTrack,NewUserTrack WHERE lower(NewArtist.name)="'.strtolower($artistName).'" AND NewAlbum.idArtist=NewArtist.id AND NewTrack.idAlbum=NewAlbum.id AND NewUserTrack.idTrack=NewTrack.id GROUP BY NewAlbum.name)
                 as temp)
             as temp2 ORDER BY rate DESC';

        $result=mysql_query($query);
        while($row=  mysql_fetch_array($result)){
            $count--;
            if($count==-1){break;}

            $playlist=new Playlist();
            $playlist->setName($row['name']);
            $queryTracks='SELECT id FROM NewTrack WHERE idAlbum='.$row['albumID'];
            $resultTracks=mysql_query($queryTracks);
            while($rowTracks=  mysql_fetch_array($resultTracks)){
                $track=$this->getTrackByID($rowTracks['id']);
                $album=$this->getAlbumByID($row['albumID'],false);
                
                $artist=new Artist();
                $artist->setID($row['artistID']);
                $artist->setName($artistName);
                
                $playlist->addSong($track,$artist,$album);
            }

            array_push($out,$playlist);
        }
        //var_dump($out);
        return $out;
    }
    
    /**
     * Save a new playlist 
     * @param Playlist $playlist 
     */
    function addPlaylist($playlist){
        if($playlist instanceof Playlist){
            $songs=$playlist->songs();
            $stringSongs=$songs[0]->id();
            for($i=1;$i<count($songs);$i++){
                $stringSongs.=','.$songs[$i]->id();
            }
            $name=$playlist->name();
            $idUser=$this->getCache('user');
            $query='INSERT INTO Playlist (name,idUser,Songs) VALUES ("'.$name.'","'.$idUser.'","'.$stringSongs.'");';
            
            mysql_query($query);
            print(mysql_error());
            
        }
    }

    /**
     * Return a playlist based on an ID
     * @param type $id
     * @return Playlist 
     */
    function getPlaylistByID($id){
        if(is_int((int)$id)){
            $query='SELECT * FROM Playlist WHERE id='.$id;
            $result=mysql_query($query);
      
            $row=mysql_fetch_array($result);
            $playlist=new Playlist();
            $playlist->setName($row['name']);
            $playlist->setID($row['id']);
            $songs=$row['Songs'];

            $songs= explode(',', $songs);

            for($i=0;$i<count($songs);$i++){
                $idTrack=$songs[$i];
                $queryArtist='SELECT NewArtist.id As ArtistID,NewAlbum.id,NewArtist.name As ArtistName FROM NewArtist,NewAlbum,NewTrack WHERE NewTrack.id='.$idTrack.' AND NewAlbum.id=NewTrack.idAlbum AND NewArtist.id=NewAlbum.idArtist';
                $resultArtist=mysql_query($queryArtist);
                $rowArtist=mysql_fetch_array($resultArtist);
                $artist=New Artist();
                $artist->setID($rowArtist['ArtistID']);
                $artist->setName($rowArtist['ArtistName']);

                $album=$this->getAlbumByID($rowArtist[1], false);

                $track=$this->getTrackByID($songs[$i]);

                $playlist->addSong($track,$artist,$album);
            }
            return $playlist;
        }
        return null;
    }

    /**
     * Returns a list of top artists based on a tag-name. This procedure is still rather
     * slow.
     * @param type $tagName
     * @return array 
     */
    public function getArtistsByTagName($tagName){
        $query1 = 'SELECT DISTINCT NewGenre.id FROM NewGenre WHERE LOWER(NewGenre.label) = "'.$tagName.'" LIMIT 1';
        $id = 0;
        if($result1 = mysql_query($query1))
            if($row1 = mysql_fetch_array($result1))
                $id = $row1[0];
        if($id == 0) return null;
        
        $query2 = 'SELECT DISTINCT NewArtist.id FROM NewArtist, NewGenre, NewArtistGenre WHERE NewArtist.id = NewArtistGenre.ArtistID AND (NewArtistGenre.Genre1ID = '.$id.' OR NewArtistGenre.Genre2ID = '.$id.' OR NewArtistGenre.Genre3ID = '.$id.')';
        if($result2 = mysql_query($query2))
        {        
            $artists = array();
            $iterator = 0;
            while($row2 = mysql_fetch_array($result2))
            {
                $artists[$iterator] = array();
                $artists[$iterator]['artistID'] = $row2['id'];
                $query3 = 'SELECT SUM(NewUserTrack.listened)*SUM(NewUserTrack.rating) FROM NewUserTrack, NewTrack, NewAlbum WHERE NewUserTrack.idTrack = NewTrack.id AND NewTrack.idAlbum = NewAlbum.id AND NewAlbum.idArtist = '.$row2['id'];
                $result3 = mysql_query($query3);
                $row3 = mysql_fetch_array($result3);
                if($row3[0])
                    $artists[$iterator]['score'] = $row3[0];
                else
                    $artists[$iterator]['score'] = 0;
                
                $iterator++;
            }
            $returnList = array();
            $length = count($artists);
            for($i = 0; $i < 3; $i++)
            {
                $max = -1;
                $artistID = 0;
                $index = 0;
                for($j = 0; $j < count($artists); $j++)
                {
                    if($artists[$j] != null && $artists[$j]['score'] > $max)
                    {
                        $max = $artists[$j]['score'];
                        $artistID = $artists[$j]['artistID'];
                        $index = $j;
                    }
                }
                if($artistID!=0)
                {
                    $artist = $this->getArtistByID($artistID, 1, 0, 3, 3);
                    array_push($returnList, $artist);
                }
                $artists[$index] = null;
            }
            return $returnList;
        }
        return null;
    }
    
    /**
     * Return the total listencount for all tags
     * @param type $max
     * @return array 
     */
    public function getGlobalStatCount($max=10){
        $query = 'SELECT NewGenre.label AS label, SUM(count) AS count FROM NewUserGenre, NewGenre WHERE NewGenre.id=idGenre GROUP BY NewUserGenre.idGenre ORDER BY count DESC';
        $result = mysql_query($query);
        $return = array();
        
        while($row = mysql_fetch_array($result)){
            $max--;
            if($max==0){
                break;
            }
            $item=array();
            $item['label']=$row['label'];
            $item['count']=(int)$row['count'];
            array_push($return,$item);
        }
        
        return $return;
    }

    /* Return the user-specific listencount for all tags 
    */
    public function getPersonalStatCount(){
        $idUser=$this->getCache('user');
        if(!$idUser || $idUser <= 0)
        {
            return null;
        }
        $query = 'SELECT NewGenre.label as label, SUM(count) AS count FROM NewUserGenre, NewGenre WHERE NewGenre.id=idGenre AND idUser='.$idUser.' GROUP BY NewUserGenre.idGenre ORDER BY count DESC';
        $result = mysql_query($query);
        $return = array();

        print(mysql_error());
        while($row = mysql_fetch_array($result)){
            $item=array();
            $item['label']=$row['label'];
            $item['count']=(int)$row['count'];
            array_push($return,$item);
        }
        
        return $return;
    }

    /** 
     * Add an object to the cache
     * @param type $name
     * @param type $key
     * @return type 
     */
    public function cache($name,$key){
        if(is_int($key)){
            if(!array_key_exists($name, $_SESSION)){
                $_SESSION[$name]=array();
            }
            array_push($_SESSION[$name],$key);
            return true;
        }
        return false;
    }
    
    /**
     * Return an object from the cache
     * @param type $name
     * @param type $pos
     * @param type $fullList
     * @return type 
     */
    public function getCache($name,$pos=0,$fullList=false){
        if(array_key_exists($name, $_SESSION)){
            if(count($_SESSION[$name])>0){
                if(!$fullList){
                    return $_SESSION[$name][$pos];
                }
                else{
                    return $_SESSION[$name];
                }
            }
        }
        return null;
        
    }
    
    /**
     * _destruct() is called by PHP automatically when an object has no references in the memory
     * Kill the session
     */
    public function __destruct(){
        if(isset($_SESSION)){
            session_write_close();
        }
    }
}
?>
